/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package API_Db;

import domain.Categorie;
import domain.Image;
import domain.Observer.I_Observer;
import domain.Observer.MeilleurEncherisseur;
import domain.Observer.Seance;
import domain.Observer.SimpleSuiveur;
import domain.Observer.Vendeur;
import domain.Produit;
import domain.Utilisateur;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.sql.Timestamp;

/**
 * 
 * -3 solde de l utilisateur insufisant pour encherir
 * -4 probleme lors de l insertion dans la table produit
 * @author Damador
 */
public class API_Db_Seance implements IAPI_Db_Seance
{

    @Override
    public int creerSeanceDB(Seance seance) throws Exception
    {
        ConnexionDB connect = ConnexionDB.getConnexion();
        ResultSet res;

        String requeteInsertion = "INSERT INTO seance "
                + "(id_seance,id_produit, prix_depart, prix_reserve, date_ouverture, date_fermeture,etat,id_vendeur) VALUES"
                + "( NULL," + seance.getProduit().getId_produit()
                + "," + seance.getPrix_depart() + ","
                + seance.getReserve() + ",'"
                + seance.getDate_ouverture() + "','"
                + seance.getDate_fermeture() + "',0,"
                + seance.getId_vendeur() + ");";

        if (connect.executerRequeteUpdate(requeteInsertion) != 0)
        {

            String requeteGetProduit = "SELECT MAX(id_seance) id_seance FROM seance;";
            res = connect.executerRequeteQuery(requeteGetProduit);

            if (res.next())
            {
                return res.getInt("id_seance");
            }
        }
        throw new Exception("Erreur lors de l'ajout de la seance");
    }

    @Override
    public List<Seance> listerSeanceDB(String condition, int nbSeance, int numPage) throws Exception
    {
        ConnexionDB connect = ConnexionDB.getConnexion();
        List<Seance> listeSeance = new ArrayList<Seance>();
        ResultSet res;
        int debut = (nbSeance * (numPage - 1));
        String getListeSeance = "SELECT s.* FROM seance s, produit p WHERE s.id_produit = p.id_produit " + condition
                + " LIMIT " + (debut) + "," + nbSeance + ";";
        System.out.println(getListeSeance);
        res = connect.executerRequeteQuery(getListeSeance);
        while (res.next())
        {
            Seance seance = new Seance();
            seance.setId_seance(res.getInt("id_seance"));
            seance.setPrix_depart(res.getDouble("prix_depart"));
            seance.setReserve(res.getDouble("prix_reserve"));
            seance.setDate_ouverture(res.getTimestamp("date_ouverture"));
            seance.setDate_fermeture(res.getTimestamp("date_fermeture"));
            seance.setEtat(res.getInt("etat"));
            seance.setObserverCollection(getListeObserverFromSeance(res.getInt("id_seance")));
            seance.setProduit(getProduitParId(res.getInt("id_produit")));
            seance.setId_vendeur(res.getInt("id_vendeur"));
            listeSeance.add(seance);
        }
        return listeSeance;
    }

    @Override
    public int getNbPagesDB(String condition, int nbSeance) throws Exception
    {
        ConnexionDB connect = ConnexionDB.getConnexion();
        ResultSet res;
        String getListeSeance = "SELECT COUNT(*) FROM seance s, produit p WHERE s.id_produit = p.id_produit " + condition + ";";
        System.out.println(getListeSeance);
        res = connect.executerRequeteQuery(getListeSeance);
        Double nombreTotalSeance = 0.00;
        if (res.next())
        {
            nombreTotalSeance = res.getDouble("COUNT(*)");
        }
        System.out.println("indb " + nombreTotalSeance + " / " + nbSeance);
        return (int) Math.ceil(nombreTotalSeance / nbSeance);
    }

    @Override
    public int rejoindreSeanceDB(int id_seance, int id_utilisateur) throws Exception
    {
        ConnexionDB connect = ConnexionDB.getConnexion();
        String requeteInsertionTableParticiper = "INSERT INTO participer VALUES (" + id_utilisateur + "," + id_seance + ");";
        return connect.executerRequeteUpdate(requeteInsertionTableParticiper);
    }

    @Override
    public synchronized int encherirDB(int id_seance, int id_utilisateur, double prix) throws Exception
    {
        ConnexionDB connect = ConnexionDB.getConnexion();
        ResultSet res;

        java.util.Date today = new java.util.Date();
        Timestamp date = new Timestamp(today.getTime());

        String requeteEncherir = "INSERT INTO encherir VALUES (" + id_utilisateur + "," + id_seance + ",'" + date + "'," + prix + ");";
        return connect.executerRequeteUpdate(requeteEncherir);
    }

    @Override
    public int quitterSeanceDB(int id_seance, int id_utilisateur) throws Exception
    {
        ConnexionDB connect = ConnexionDB.getConnexion();
        String requeteDeleteParticipation = "DELETE FROM participer WHERE id_seance = " + id_seance + " AND id_utilisateur = " + id_utilisateur + ";";

        return connect.executerRequeteUpdate(requeteDeleteParticipation);
    }

    //TODO encode du message
    @Override
    public int posterMessageDB(int id_seance, int id_utilisateur, String message) throws Exception
    {
        ConnexionDB connect = ConnexionDB.getConnexion();

        java.util.Date today = new java.util.Date();
        Timestamp date = new Timestamp(today.getTime());

        String requetePosterMessage = "INSERT INTO poster_message VALUES (" + id_utilisateur + "," + id_seance + ",'" + date + "','" + message + "');";
        return connect.executerRequeteUpdate(requetePosterMessage);
    }

    @Override
    public Utilisateur getMeilleurEncherisseurDB(int id_seance) throws Exception
    {
        API_Db_Utilisateur apiDbUser = new API_Db_Utilisateur();
        ConnexionDB connect = ConnexionDB.getConnexion();
        ResultSet res;

        String requeteGetParticipants = "SELECT id_utilisateur FROM encherir WHERE Montant = (SELECT MAX(montant) FROM encherir WHERE id_seance =" + id_seance + ");";

        res = connect.executerRequeteQuery(requeteGetParticipants);

        if (res.next())
        {
            return apiDbUser.getUtilisateurParId(res.getInt("id_utilisateur"));
        }
        return null;
    }

    @Override
    public double getMeilleurEnchereDB(int id_seance) throws Exception
    {
        ConnexionDB connect = ConnexionDB.getConnexion();
        ResultSet res;
        String requeteGetMeilleurEnchere = "SELECT MAX(montant) montant FROM encherir WHERE id_seance=" + id_seance;
        res = connect.executerRequeteQuery(requeteGetMeilleurEnchere);
        Double montant = 0.00;
        if (res.next())
        {
            montant = res.getDouble("montant");
        }
        return montant;
    }

    @Override
    public int changerEtatSeanceDB(int id_seance, int etat) throws Exception
    {
        ConnexionDB connect = ConnexionDB.getConnexion();

        String requeteUpdateEtatSeance = "UPDATE seance SET etat=" + etat + " WHERE id_seance =" + id_seance;

        return connect.executerRequeteUpdate(requeteUpdateEtatSeance);
    }

    @Override
    public int ajouterProduitDB(Produit produit) throws Exception
    {
        ConnexionDB connect = ConnexionDB.getConnexion();
        ResultSet res;
        String requeteInsertionProduit = "INSERT INTO produit (id_produit,id_categorie,titre,description)"
                + " VALUES (NULL," + produit.getCategorie().getId_categorie() + ",'" + produit.getTitre() + "','" + produit.getDescription() + "');";

        if (connect.executerRequeteUpdate(requeteInsertionProduit) != 0)
        {

            String requeteGetProduit = "SELECT MAX(id_produit) id_produit FROM produit;";
            res = connect.executerRequeteQuery(requeteGetProduit);

            if (res.next())
            {
                return res.getInt("id_produit");
            }
        }
        throw new Exception("Erreur lors de l'ajout du produit");
    }

    @Override
    public Produit getProduitParId(int id_produit) throws Exception
    {
        ConnexionDB connect = ConnexionDB.getConnexion();
        ResultSet res;

        String requeteGetProduit = "SELECT * FROM produit WHERE id_produit = " + id_produit;

        res = connect.executerRequeteQuery(requeteGetProduit);
        Produit prod = new Produit();

        if (res.next())
        {
            prod.setId_produit(res.getInt("id_produit"));
            prod.setCategorie(getCategorieById(res.getInt("id_categorie")));
            prod.setDescription(res.getString("description"));
            prod.setTitre(res.getString("titre"));
            prod.setImages(getImagesByIdProduit(id_produit));
        }
        return prod;
    }

    @Override
    public Seance getSeanceById(int id_seance) throws Exception
    {
        ConnexionDB connect = ConnexionDB.getConnexion();
        ResultSet res;

        String requeteGetSeance = "SELECT * FROM seance WHERE id_seance = " + id_seance;

        res = connect.executerRequeteQuery(requeteGetSeance);
        Seance seance = new Seance();

        if (res.next())
        {
            seance.setDate_fermeture(res.getTimestamp("date_fermeture"));
            seance.setDate_ouverture(res.getTimestamp("date_ouverture"));
            seance.setEtat(res.getInt("etat"));
            seance.setId_seance(res.getInt("id_seance"));
            seance.setObserverCollection(getListeObserverFromSeance(seance.getId_seance()));
            seance.setPrix_depart(res.getDouble("prix_depart"));
            seance.setReserve(res.getDouble("prix_reserve"));
        seance.setId_vendeur(res.getInt("id_vendeur"));
            seance.setProduit(getProduitParId(res.getInt("id_produit")));
        }
        return seance;
    }

    @Override
    public List<I_Observer> getListeObserverFromSeance(int id_seance) throws Exception
    {
        ConnexionDB connect = ConnexionDB.getConnexion();
        ResultSet res;
        List<I_Observer> listeObservers = new ArrayList<I_Observer>();
        API_Db_Utilisateur apiDbUser = new API_Db_Utilisateur();
        
        //Ajout des participants
        String requeteGetParticipants = "SELECT * FROM participer WHERE id_seance=" + id_seance;
        res = connect.executerRequeteQuery(requeteGetParticipants);
        while (res.next())
        {
            listeObservers.add(new SimpleSuiveur(apiDbUser.getUtilisateurParId(res.getInt("id_utilisateur"))));
        }
        //Ajout du vendeur
        String requeteGetVendeur = "SELECT id_vendeur FROM seance WHERE id_seance=" + id_seance;
        res = connect.executerRequeteQuery(requeteGetVendeur);
        if (res.next())
        {
            listeObservers.add(new Vendeur(apiDbUser.getUtilisateurParId(res.getInt("id_vendeur"))));
        }
        //Ajout du meilleur encherisseur
        Utilisateur user = getMeilleurEncherisseurDB(id_seance);
        if(user != null)
            listeObservers.add(new MeilleurEncherisseur(user));
        
        return listeObservers;
    }

    @Override
    public int ajouterImageProduitDB(int id_produit, List<Image> images) throws Exception
    {
        ConnexionDB connect = ConnexionDB.getConnexion();
        for (int i = 0; i < images.size(); i++)
        {
            String insertImage = "INSERT INTO image VALUES (null," + id_produit + ",'" + images.get(i).getCheminFichier() + "')";

            if (connect.executerRequeteUpdate(insertImage) == 0)
            {
                return 0;
            }
        }
        return 1;
    }

    @Override
    public Categorie getCategorieById(int id_categorie) throws Exception
    {
        ConnexionDB connect = ConnexionDB.getConnexion();
        ResultSet res;

        String requeteGetCategorie = "SELECT * FROM categorie WHERE id_categorie = " + id_categorie;

        res = connect.executerRequeteQuery(requeteGetCategorie);
        Categorie categ = new Categorie();

        if (res.next())
        {
            categ.setId_categorie(res.getInt("id_categorie"));
            categ.setNom(res.getString("nom"));
        }
        return categ;
    }

    @Override
    public List<Image> getImagesByIdProduit(int id_produit) throws Exception
    {
        ConnexionDB connect = ConnexionDB.getConnexion();
        ResultSet res;
        List<Image> images = new ArrayList<Image>();
        String requeteGetImage = "SELECT * FROM image WHERE id_produit=" + id_produit;
        res = connect.executerRequeteQuery(requeteGetImage);
        while (res.next())
        {
            Image image = new Image();
            image.setCheminFichier(res.getString("chemin"));
            image.setId_image(res.getInt("id_image"));
            images.add(image);
        }
        return images;
    }

    @Override
    public boolean participeASeance(int id_seance, int id_utilisateur) throws Exception
    {
        ConnexionDB connect = ConnexionDB.getConnexion();
        ResultSet res;

        String requeteParticipeASeance = "SELECT * FROM participer WHERE id_seance = " + id_seance + " AND id_utilisateur = " + id_utilisateur + ";";

        res = connect.executerRequeteQuery(requeteParticipeASeance);

        if (res.next())
            return true;
        return false;
    }

    @Override
    public List<Categorie> getAllCategorie() throws Exception {
        ConnexionDB connect = ConnexionDB.getConnexion();
        ResultSet res;
        List<Categorie> listeCateg = new ArrayList<Categorie>();

        String getAllSeance = "SELECT * FROM categorie";

        res = connect.executerRequeteQuery(getAllSeance);

        while(res.next())
        {
            listeCateg.add(getCategorieById(res.getInt("id_categorie")));
        }
        return listeCateg;
    }
}
